//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Windows;
using System.Windows.Input;
using OpenLS.Chart.UI.Internals;
using OpenLS.Drawing;

namespace OpenLS.Chart.UI.Internals
{
    static class FormatHelper
    {


        public static bool GetHandlesChartCommands(DependencyObject obj)
        {
            return (bool)obj.GetValue(HandlesChartCommandsProperty);
        }

        public static void SetHandlesChartCommands(DependencyObject obj, bool value)
        {
            obj.SetValue(HandlesChartCommandsProperty, value);
        }

        // Using a DependencyProperty as the backing store for HandlesChartCommands.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HandlesChartCommandsProperty =
            DependencyProperty.RegisterAttached("HandlesChartCommands", typeof(bool), typeof(FormatHelper), new UIPropertyMetadata(false, onHandlesChartCommands));

        private static void onHandlesChartCommands(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            EnableCommandBindings((FrameworkElement) d);
        }


        static void EnableCommandBindings (FrameworkElement element)
        {
            element.CommandBindings.Add(new CommandBinding(ChartCommands.AddTitle, onAddTitle, onCanAddTitle));
            element.CommandBindings.Add(new CommandBinding(ChartCommands.AddLegend, onAddLegend, onCanAddLegend));
            element.CommandBindings.Add(new CommandBinding(ChartCommands.FormatDataSeries, onFormatDataSeries));
            element.CommandBindings.Add(new CommandBinding(ChartCommands.UnformatDataSeries, onUnformatDataSeries));
            element.CommandBindings.Add(new CommandBinding(ChartCommands.FormatDataPoint, onFormatDataPoint));
            element.CommandBindings.Add(new CommandBinding(ChartCommands.UnformatDataPoint, onUnformatDataPoint, onHasDataPoint));
            element.CommandBindings.Add(new CommandBinding(ChartCommands.AddDataLabels, onAddDataLabels,
                                                           onHasNoDataLabels));
            element.CommandBindings.Add(new CommandBinding(ChartCommands.FormatDataLabels, onFormatDataLabels,
                                                           onHasDataLabels));
        }

        private static void onCanAddTitle(object sender, CanExecuteRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var chart = ChartElement.GetChartArea(element);
            args.CanExecute = chart.Title == null;
         
        }

        private static void onCanAddLegend(object sender, CanExecuteRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var chart = ChartElement.GetChartArea(element);
            args.CanExecute = chart.Legend == null;
        }

        private static void onAddTitle(object sender, ExecutedRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var chart = ChartElement.GetChartArea(element);
            chart.Title = new Title(new TextBody(UIStringTable.DefaultTitle)); 
            args.Handled = true;
        }

        private static void onAddLegend(object sender, ExecutedRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var chart = ChartElement.GetChartArea(element);
            chart.Legend = new Legend(chart);
            args.Handled = true;
        }
        
        private static void onAddDataLabels(object sender, ExecutedRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            Series series = SeriesElement.GetSeries(element);
            var labelsOwner = (IDataLabelsOwner)series;
            const DataLabelPosition position = DataLabelPosition.Right;
            var dataLabels = new DataLabels {Position = position};
            labelsOwner.DataLabels = dataLabels;

        }

        private static void onHasNoDataLabels(object sender, CanExecuteRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var series = (IDataLabelsOwner)SeriesElement.GetSeries(element);
            if (series == null)
                return;
            args.CanExecute = series.DataLabels == null;
            args.Handled = true;
        }
        private static void onHasDataLabels(object sender, CanExecuteRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var series = (IDataLabelsOwner)SeriesElement.GetSeries(element);
            if (series == null)
                return;
            args.CanExecute = series.DataLabels != null;
            args.Handled = true;
        }
        private static void onFormatDataPoint(object sender, ExecutedRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var series = (IDataPointOwner)SeriesElement.GetSeries(element);
            var value = (NumericValue)element.DataContext;
            if (!series.DataPoints.Contains(value.Index))
                series.DataPoints.Add(new DataPoint(value.Index));
            DataPoint dp = series.DataPoints[value.Index];
            PropertyHelper.ShowPropertiesFor(dp, element, ChartCommands.FormatDataPoint.Text, PropertyTabHint.None);
        }

        private static void onHasDataPoint(object sender, CanExecuteRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var series = (IDataPointOwner)SeriesElement.GetSeries(element);
            if (series == null)
                return;
            var value = element.DataContext as NumericValue;
            if (value != null)
                args.CanExecute = series.DataPoints.Contains(value.Index);
            args.Handled = true;

        }

        private static void onUnformatDataPoint(object sender, ExecutedRoutedEventArgs args)
        {
            var element = (FrameworkElement)args.Source;
            var series = (IDataPointOwner)SeriesElement.GetSeries(element);
            var value = (NumericValue)element.DataContext;
            if (series.DataPoints.Contains(value.Index))
                series.DataPoints.RemoveAt(value.Index);
            args.Handled = true;
        }

        static void onFormatDataSeries(object sender, ExecutedRoutedEventArgs args)
        {
            var e = (FrameworkElement)args.Source;
            PropertyHelper.ShowPropertiesFor(SeriesElement.GetSeries(e), e, ChartCommands.FormatDataSeries.Text, PropertyTabHint.None);

        }
        static void onUnformatDataSeries(object sender, ExecutedRoutedEventArgs args)
        {
            var e = (FrameworkElement)args.Source;
            Series series = SeriesElement.GetSeries(e);
            series.ShapeProperties = null;
            args.Handled = true;
        }
        static void onFormatDataLabels(object sender, ExecutedRoutedEventArgs args)
        {
            var e = (FrameworkElement)args.Source;
            Series series = SeriesElement.GetSeries(e);
            var labelsOwner = series as IDataLabelsOwner;
            if (labelsOwner == null) return;
            PropertyHelper.ShowPropertiesFor(labelsOwner.DataLabels, e, ChartCommands.FormatDataSeries.Text, PropertyTabHint.None);

        }

    }
}
